/*
 * Copyright (c) 2008-2011, Petr Panteleyev
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *    3. The name of the author may not be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.panteleyev.wordpress;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.EventObject;
import java.util.concurrent.ExecutionException;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingWorker;
import javax.swing.text.JTextComponent;

import org.jdesktop.swingx.JXCollapsiblePane;
import org.jdesktop.swingx.JXStatusBar;
import org.panteleyev.blogapi.Blog;
import org.panteleyev.blogapi.BlogEntry;
import org.panteleyev.blogapi.CommentsStatus;
import org.panteleyev.blogapi.MetaWeblogEntry;
import org.panteleyev.blogapi.WordPressAccount;
import org.panteleyev.blogapi.WordPressPage;
import org.panteleyev.blogapi.WordPressTag;
import org.panteleyev.blogclient.BlogPostEditorFrame;
import org.panteleyev.blogclient.BloggerOutboxFrame;
import org.panteleyev.blogclient.DateTimePicker;
import org.panteleyev.blogclient.FontManager;
import org.panteleyev.blogclient.Icon;
import org.panteleyev.blogclient.Options;
import org.panteleyev.blogclient.PreviewFrame;
import org.panteleyev.blogclient.Previewer;
import org.panteleyev.blogclient.TagListManager;
import org.panteleyev.blogclient.UI;
import org.panteleyev.blogclient.events.OutboxChangedEvent;
import org.panteleyev.blogclient.events.TagsUpdatedEvent;
import org.panteleyev.blogclient.events.TemplatesChangedEvent;
import org.panteleyev.html.Editor;
import org.panteleyev.html.PlainEditor;
import org.panteleyev.otherblogs.CategorySelectionDialog;
import org.panteleyev.swing.CollapseButton;
import org.panteleyev.swing.OSUtil;
import org.panteleyev.swing.SwingFactory;
import org.panteleyev.swing.filefilters.FileFilter;
import org.panteleyev.swing.filefilters.ImageFileFilter;
import org.panteleyev.swing.filefilters.PowerPointFileFilter;
import org.panteleyev.utilities.events.AppEventListener;

public class WPEditorFrame extends BlogPostEditorFrame<WordPressUserProfile,MetaWeblogEntry> {
    private JTextField              subjectEdit;
    private JComboBox<String>       blogsComboBox = new JComboBox<>();
    private DateTimePicker          datePicker;
    private JTextField              labelsEdit;
    private JCheckBox               manualDateCheck;
    private JButton                 labelsButton;
    private JComboBox<String>       commentsStatusComboBox;
    private JCheckBox               draftCheckBox;
    private JComboBox<String>       pingStatusComboBox;
    private JXCollapsiblePane       collPane;
    private JLabel                  fileNameField = new JLabel();
    private JTextPane               textPane = new JTextPane();

    private class ReloadTagsThread extends SwingWorker<Object,Object> {
        ReloadTagsThread() {
            startLongOperation();
        }

        @Override
        protected Object doInBackground() throws Exception {
            account.updateTags(getSelectedBlog());
            return null;
        }

        @Override
        protected void done() {
            try {
                get();
                getProfile().storeTags(account);
                updateTagsControls();
            } catch (InterruptedException | ExecutionException | IOException ex) {
                handleException(ex);
            } finally {
                finishLongOperation();
            }
        }
    }

    private final class ImageUploadThread extends SwingWorker<String,Object> {
        private Blog blog;
        private File file;
        private FileFilter filter;

        ImageUploadThread(Blog blog, File file, FileFilter filter) {
            this.blog = blog;
            this.file = file;
            this.filter = filter;
        }

        @Override
        protected String doInBackground() throws Exception {
            return getAccount().newMediaObject(blog, file);
        }

        @Override
        protected void done() {
            try {
                String url = get();
                if (url != null) {
                    if (filter instanceof ImageFileFilter) {
                        onInsertImageReference(url);
                    } else {
                        onInsertReference(url);
                    }
                }
            } catch (ExecutionException ex) {
                handleException(ex.getCause());
            } catch (InterruptedException ignore) {
            } finally {
                prDialog.setVisible(false);
            }
        }
    }

    private final class PostingThread extends SwingWorker<Object,Object> {
        private boolean close;

        PostingThread(boolean close) {
            this.close = close;
            getBusyLabel().setBusy(true);
            getPublishAction().setEnabled(false);
            getPublishAndContinueAction().setEnabled(false);
        }

        @Override
        protected Object doInBackground() throws Exception {
            if (_post.getId() == null || _post.getId().length() == 0) {
                getAccount().createEntry(_post);
                // TODO: reload window fields
            } else {
                getAccount().updateEntry(_post);
            }

            return null;
        }

        @Override
        protected void done() {
            try {
                get();

                ArrayList<String> labels = _post.getTags();
                if (getAccount().addTags(getSelectedBlog(), labels)) {
                    getProfile().storeTags(getAccount());
                    getProfile().sendApplicationEvent(new TagsUpdatedEvent(this));
                }

                /* Remove outbox file if exists and we are online */
                if (getProfile().isOnline() && (outboxFile != null)) {
                    outboxFile.delete();
                    outboxFile = null;
                    getProfile().sendApplicationEvent(new OutboxChangedEvent(this));
                }
                if (close) {
                    afterPostSent();
                }
            } catch (ExecutionException ex) {
                handleException(ex.getCause());
            } catch (InterruptedException ignore) {
            } catch (Exception ex) {
                handleException(ex);
            } finally {
                getPublishAction().setEnabled(true);
                getPublishAndContinueAction().setEnabled(true);
                getBusyLabel().setBusy(false);
            }
        }
    }

    private String[] statusLabels = {
        L10N.POST_WINDOW_STATUS_DEFAULT.s(),
        L10N.POST_WINDOW_STATUS_OPEN.s(),
        L10N.POST_WINDOW_STATUS_CLOSED.s(),
    };

    private WordPressAccount        account;
    private BlogEntry               _post;
    private JTextComponent          _focusedText;
    private JMenu                   _labelsMenu = new JMenu();

    private File                    outboxFile;

    private PlainEditor             plainEditor = new PlainEditor();
    private Editor                  editor = plainEditor;

    private ArrayList<Integer>      selectedCategories = new ArrayList<>();

    private AbstractAction          openTagsListAction;
    private AbstractAction          uploadMediaObjectAction;
    private UploadProgressDialog    prDialog;

    private TagListManager          tagListManager;

    private void constructor(WordPressUserProfile profile, BlogEntry post, File file) {
        this.account = profile.getAccount();
        outboxFile = file;
        _post = post;

        createActions();
        initComponents();
        createMenuBar();

        tagListManager = new TagListManager(labelsEdit);

        plainEditor.setEditor(textPane);
        plainEditor.newDocument();
        editor = plainEditor;

        blogsComboBox.setModel(new BlogComboBoxModel(getAccount().getBlogs()));
        blogsComboBox.setVisible(getAccount().getBlogsCount() > 0);

        /* Fill fields */
        if (_post != null) {
            subjectEdit.setText(_post.getSubject());
            textPane.setText(_post.getBody());
            datePicker.setDate(_post.getDateCreated());

            if (_post.getBlog() == null) {
                if (getAccount().getBlogsCount() > 0) {
                    blogsComboBox.setSelectedIndex(0);
                }
            } else {
                blogsComboBox.setSelectedIndex(getAccount().getBlogs().indexOf(_post.getBlog()));
                blogsComboBox.setEnabled(false);
            }

            /* Labels */
            ArrayList<String> labels = _post.getTags();
            StringBuilder b = new StringBuilder();
            for (int i = 0, labelCount = labels.size(); i < labelCount; i++) {
                b.append(labels.get(i));
                if (i != labelCount - 1) {
                    b.append(", ");
                }
            }
            labelsEdit.setText(b.toString());

            commentsStatusComboBox.setSelectedIndex(_post.getCommentsStatus().ordinal());
            pingStatusComboBox.setSelectedIndex(_post.getPingStatus().ordinal());

            manualDateCheck.setSelected(true);
            datePicker.setEnabled(true);
            draftCheckBox.setSelected(_post.isDraft());
            setTitle();

            if (_post instanceof WordPressPage) {
                labelsEdit.setEnabled(false);
                getPublishLaterAction().setEnabled(false);
            }
        } else {
            setEmptyPost();
        }

        /* Setup undo/redo */
        updateUndoRedo(false, false);
        getTextUndoManager().addComponent(textPane);
        getTextUndoManager().addComponent(subjectEdit);
        getTextUndoManager().addComponent(labelsEdit);

        addAppEventListener(TemplatesChangedEvent.class, new AppEventListener() {
            @Override
            public void eventReceived(EventObject event) {
                textPane.setComponentPopupMenu(generateEditorPopupMenu());
            }
        });

        addAppEventListener(TagsUpdatedEvent.class, new AppEventListener() {
            @Override
            public void eventReceived(EventObject event) {
                updateTagsControls();
            }
        });
    }

    private void updateTagsControls() {
        Blog blog = getSelectedBlog();
        if (blog != null) {
            ArrayList<WordPressTag> tags = getAccount().getTags(blog);
            _labelsMenu = tagListManager.buildTagsMenu(tags);
            openTagsListAction.setEnabled(tags != null && tags.size() > 0);
        }
    }

    private void initComponents() {
        getContentPane().setLayout(new BorderLayout());

        getContentPane().add(SwingFactory.createToolBarPanel(
            createProfileToolBar(false, true),
            Box.createHorizontalGlue(),
            getBusyLabel(),
            Box.createHorizontalStrut(5)
        ), BorderLayout.NORTH);

        JPanel centralPanel = new JPanel(new BorderLayout());

        centralPanel.add(SwingFactory.createPanel(BorderFactory.createEmptyBorder(5, 5, 5, 5), SwingFactory.LAYOUT.BOX_X,
            new JLabel(getPostWindowSubjectLabelText()),
            Box.createHorizontalStrut(3),
            subjectEdit = new JTextField(),
            Box.createHorizontalStrut(5),
            blogsComboBox
        ), BorderLayout.NORTH);

        textPane.setComponentPopupMenu(generateEditorPopupMenu());
        textPane.setFont(FontManager.getEditorFont());
        textPane.setMargin(UI.EDITOR_MARGIN);
        centralPanel.add(new JScrollPane(textPane), BorderLayout.CENTER);

        getContentPane().add(centralPanel, BorderLayout.CENTER);

        // Status bar
        JXStatusBar bar = new JXStatusBar();
        bar.add(fileNameField, new JXStatusBar.Constraint(JXStatusBar.Constraint.ResizeBehavior.FILL));
        getContentPane().add(bar, BorderLayout.SOUTH);

        JPanel optionsPanel = SwingFactory.createPanel(BorderFactory.createEmptyBorder(5, 5, 5, 5),
            SwingFactory.LAYOUT.BOX_X,
            draftCheckBox = new JCheckBox(getPostWindowDraftCheckBoxText()),
            Box.createHorizontalStrut(5),
            new JButton(new AbstractAction(L10N.POST_WINDOW_CATEGORIES_BUTTON.s()) {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    Blog blog = getSelectedBlog();
                    if (blog != null) {
                        CategorySelectionDialog dial = new CategorySelectionDialog(WPEditorFrame.this, blog.getCategories(), selectedCategories);
                        if (dial.showDialog()) {
                            selectedCategories = dial.getSelectedCategories();
                        }
                    }
                }
            }),
            Box.createHorizontalStrut(10),
            new JLabel(L10N.POST_WINDOW_COMMENTS_LABEL.s()),
            Box.createHorizontalStrut(3),
            commentsStatusComboBox = new JComboBox<>(statusLabels),
            Box.createHorizontalStrut(10),
            new JLabel(L10N.POST_WINDOW_PING_STATUS_LABEL.s()),
            Box.createHorizontalStrut(3),
            pingStatusComboBox = new JComboBox<>(statusLabels),
            Box.createHorizontalGlue()
        );

        SwingFactory.setWidthMaximumToPreferred(commentsStatusComboBox, pingStatusComboBox);

        collPane = new JXCollapsiblePane();
        collPane.setLayout(new BoxLayout(collPane.getContentPane(), BoxLayout.Y_AXIS));
        SwingFactory.add(collPane,
            new JSeparator(),
            optionsPanel
        );
        collPane.setCollapsed(true);

        JButton tButton = new CollapseButton(collPane);
        tButton.setFocusable(false);

        JPanel panel;
        centralPanel.add(panel = SwingFactory.createPanel(BorderFactory.createEmptyBorder(5, 0, 0, 5), SwingFactory.LAYOUT.BOX_X,
            SwingFactory.createPanel(null, SwingFactory.LAYOUT.BOX_Y,
                SwingFactory.createPanel(BorderFactory.createEmptyBorder(0, 5, 5, 5),
                    SwingFactory.LAYOUT.BOX_X,
                    new JLabel(L10N.POST_WINDOW_LABELS_LABEL.s()),
                    Box.createHorizontalStrut(3),
                    labelsEdit = new JTextField(),
                    Box.createHorizontalStrut(3),
                    labelsButton = new JButton(openTagsListAction),
                    Box.createHorizontalStrut(3),
                    new JButton(getUpdateTagsAction()),
                    Box.createHorizontalStrut(3),
                    new JSeparator(JSeparator.VERTICAL),
                    Box.createHorizontalStrut(3),
                    manualDateCheck = new JCheckBox(new AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent arg0) {
                            datePicker.setEnabled(manualDateCheck.isSelected());
                        }
                    }),
                    datePicker = new DateTimePicker()
                ),
                collPane
            ),
            tButton
        ), BorderLayout.SOUTH);

        SwingFactory.setAlignmentY(panel, TOP_ALIGNMENT);

        subjectEdit.addFocusListener(new java.awt.event.FocusAdapter() {
            @Override
            public void focusGained(java.awt.event.FocusEvent evt) {
                _focusedText = subjectEdit;
            }
            @Override
            public void focusLost(java.awt.event.FocusEvent evt) {
                setTitle();
            }
        });

        blogsComboBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                updateTagsControls();
            }
        });

        Options.getBounds(this);
    }

    @Override
    public void setVisible(boolean b) {
        super.setVisible(b);
        textPane.requestFocus();
    }

    /** Creates new form WPEditorFrame
     * @param profile
     * @param post
     */
    public WPEditorFrame(WordPressUserProfile profile, BlogEntry post) {
        super(profile);
        constructor(profile, post, null);
    }

    public WPEditorFrame(WordPressUserProfile profile, BlogEntry post, File file) {
        super(profile);
        constructor(profile, post, file);
    }

    private void createActions() {
        openTagsListAction = new AbstractAction(null, Icon.FORWARD.i()) {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                onOpenTagsList();
            }
        };

        uploadMediaObjectAction = new AbstractAction(L10N.WORDPRESS_UPLOAD_FILE_ACTION.s(), Icon.EMPTY.i()) {
            @Override
            public void actionPerformed(ActionEvent e) {
                onUploadMediaObject();
            }
        };

        uploadMediaObjectAction.setEnabled(getProfile().isOnline());
        getUpdateTagsAction().setEnabled(getProfile().isOnline());
    }

    private void createMenuBar() {
        createMenuBar(
            createFileMenu(),
            createEditMenu(
                getUndoAction(),
                getRedoAction(),
                null,
                getCutAction(),
                getCopyAction(),
                getPasteAction(),
                null,
                getEditInsertReferenceAction(),
                getEditInsertImageAction(),
    //        insertAdvUserReferenceAction),
                null,
                uploadMediaObjectAction,
                null,
                generateQuotesSubmenu(),
                generateSymbolsSubmenu(),
                getTemplateMenu(),
                null,
                getEditTypografAction()
            ),
            generateFormatMenu(),
            createEntryMenu(),
            createProfileMenu(),
            createToolsMenu(),
            createWindowMenu(),
            createHelpMenu()
        );

        getDeleteEntryAction().setEnabled(false);
    }

    @Override
    public BlogEntry getPost() { return _post; }
///////    public String getPostID() { return (_post == null)? null : _post.getId(); }
    public WordPressAccount getAccount() { return account; }


    void saveAs(BlogEntry entry, File file) {
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file))) {
            out.writeObject(entry);
        } catch (Exception e) {
            handleException(e);
        }
    }

    @Override
    protected MetaWeblogEntry createPostObject() {
        int index = blogsComboBox.getSelectedIndex();
        if (index == -1) {
            return null;
        }
        Blog blog = getAccount().getBlog(index);
        MetaWeblogEntry post = getAccount().newEntryObject(blog);

        setEntryObject(post);

        return post;
    }

    private void setEntryObject(BlogEntry entry) {
        if (_post != null) {
            entry.setId(_post.getId());
        }

        entry.setSubject(subjectEdit.getText());
        entry.setBody(editor.getTextForPost());
        entry.setCategories(selectedCategories);

        if (manualDateCheck.isSelected()) {
            entry.setDateCreated(datePicker.getDate());
        } else {
            entry.setDateCreated(new Date());
        }

        /* Draft */
        entry.setDraft(draftCheckBox.isSelected());

        /* Tags */
        ArrayList<String> tags = tagListManager.getTags();
        if (tags != null) {
            entry.setTags(tags);
        }

        entry.setCommentsStatus(CommentsStatus.values()[commentsStatusComboBox.getSelectedIndex()]);
        entry.setPingStatus(CommentsStatus.values()[pingStatusComboBox.getSelectedIndex()]);

//        Person author = new Person("Petr Panteleyev", null, "petr.panteleyev@gmail.com");
//        newEntry.getAuthors().add(author);

    }

    private Blog getSelectedBlog() {
        int index = blogsComboBox.getSelectedIndex();
        if (index == -1) {
            return null;
        } else {
            return getAccount().getBlog(index);
        }
    }

    private void onPost(boolean close) {
        int index = blogsComboBox.getSelectedIndex();
        if (index == -1) {
            return;
        }

        Blog blog = getAccount().getBlog(index);
        if (_post == null) {
            _post = getAccount().newEntryObject(blog);
        } else {
            _post.setBlog(blog);
        }

        setEntryObject(_post);

        new PostingThread(close).execute();
    }

    private void setTitle() {
        StringBuilder b = new StringBuilder();

        final String subjText = subjectEdit.getText();
        if (subjText.length() != 0) {
            b.append(subjText);
        } else {
            final String t = (_post == null)? getPostWindowNewPostTitle() : getPostWindowEditPostTitle();
            b.append(t);
        }

        setTitle(b.toString());
    }

    @Override
    public void insertText(String text) {
        if (_focusedText != null) {
            _focusedText.replaceSelection(text);
            _focusedText.requestFocus();
        }
    }

    @Override
    public String getSelectedText() {
        return editor.getSelectedText();
    }

    @Override
    public Editor getEditor() {
        return editor;
    }

    private void onOpenTagsList() {
        if (_labelsMenu != null) {
            int x = labelsButton.getX();
            int y = labelsButton.getY();
            _labelsMenu.getPopupMenu().show(labelsButton.getParent(), x, y);
        }
    }

    @Override
    protected void setEmptyPost() {
        _post = null;
        subjectEdit.setText("");
        textPane.setText("");
        if (getAccount().getBlogsCount() > 0) {
            blogsComboBox.setSelectedIndex(0);
        }
        labelsEdit.setText("");
        commentsStatusComboBox.setSelectedIndex(0);
        manualDateCheck.setSelected(false);
        datePicker.setEnabled(false);
        datePicker.setDate(new Date());
        setTitle();
    }

    @Override
    public void onPublish() {
        onPost(true);
    }

    @Override
    public void onPublishAndContinue() {
        onPost(false);
    }

    @Override
    public void onPublishLater() {
        int index = blogsComboBox.getSelectedIndex();

        Blog blog = getAccount().getBlog(index);
        if (_post == null) {
            _post = getAccount().newEntryObject(blog);
        } else {
            _post.setBlog(blog);
        }

        setEntryObject(_post);

        /* File name */
        File saveFile = null;
        if (outboxFile == null) {
            String fName = BloggerOutboxFrame.getOutboxFileName();
            saveFile = new File(getProfile().getOutboxDirectory(), fName);
        } else {
            saveFile = outboxFile;
        }
        saveAs(_post, saveFile);
        getProfile().sendApplicationEvent(new OutboxChangedEvent(this));

        afterPostSent();
    }

    @Override
    public void onPreviewEntry() {
        int index = blogsComboBox.getSelectedIndex();
        if (index == -1) {
            return;
        }

        Blog blog = getAccount().getBlog(index);
        BlogEntry post = getAccount().newEntryObject(blog);

        post.setSubject(subjectEdit.getText());
        post.setBody(editor.getTextForPreview(true));
        if (datePicker.isEnabled()) {
            post.setDateCreated(datePicker.getDate());
        } else {
            post.setDateCreated(new Date());
        }

        try {
            Previewer previewer = new Previewer(post);

            if (Options.getUseExternalPreview()) {
                OSUtil.runBrowser(previewer.getFullFileURL().toString());
            } else {
                PreviewFrame<?> pFrame = PreviewFrame.findPreviewFrame(PreviewFrame.class, this);
                if (pFrame == null) {
                    pFrame = new PreviewFrame<>(getProfile(), this);
                }
                pFrame.setContent(null, previewer.getFullFileURL());
                pFrame.setVisible(true);
            }
        } catch (Exception e) {
            handleException(e);
        }
    }

    @Override
    public void onDeleteEntry() {
    }

    private void onUploadMediaObject() {
        int index = blogsComboBox.getSelectedIndex();
        if (index == -1) {
            return;
        }

        JFileChooser dial = new JFileChooser();
        dial.setAcceptAllFileFilterUsed(false);
        dial.setDialogTitle("Upload File");
        dial.setMultiSelectionEnabled(false);
 //       dial.addChoosableFileFilter(new PdfFileFilter());
        dial.addChoosableFileFilter(new PowerPointFileFilter());
        dial.addChoosableFileFilter(new ImageFileFilter());

        if (dial.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            Blog blog = getAccount().getBlog(index);
            SwingWorker<?,?> worker = new ImageUploadThread(blog, dial.getSelectedFile(), (FileFilter)dial.getFileFilter());
            worker.execute();
            prDialog = new UploadProgressDialog(WPEditorFrame.this, worker);
            prDialog.showDialog();
        }
    }

    @Override
    public void onUpdateTags() {
        new ReloadTagsThread().execute();
    }
}
